package com.nikkerball.apps.darkhorse.model.core;

import com.nikkerball.apps.darkhorse.model.base.Person;
import com.nikkerball.apps.darkhorse.model.change.ChangeEvent;
import com.nikkerball.apps.darkhorse.model.change.ChangeValue;
import com.nikkerball.apps.darkhorse.model.evaluation.subject.SubjectEvaluation;
import com.nikkerball.apps.darkhorse.model.evaluation.topic.TopicEvaluation;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.Type;
import org.joda.time.LocalDate;

import javax.persistence.*;
import java.util.List;

import static org.hibernate.annotations.CascadeType.*;

/**
 * Represents a Learner
 */
@Entity
@Table(name = "Learner")
public class Learner extends Person {

    // ----- instance fields -----

    private LocalDate birthDate;

    private List<ClassYear> classYears;

    private List<SubjectEvaluation> subjectEvaluations;

    private List<TopicEvaluation> topicEvaluations;

    // ----- constructors -----

    public Learner() {
        super();
    }

    public Learner(String name, String surname) {
        super(name, surname);
    }

    // ----- public methods -----

    @Type(type = "org.joda.time.contrib.hibernate.PersistentLocalDate")
    @Column(nullable = false)
    public LocalDate getBirthDate() {
        return this.birthDate;
    }

    public void setBirthDate(LocalDate birthDate) {
        this.birthDate = birthDate;
    }

    @Transient
    public List<ChangeValue> getChangeValues(ChangeEvent changeEvent) {
        List<ChangeValue> changeValues = super.getChangeValues(changeEvent);
        changeValues.add(new ChangeValue("birthDate", getBirthDate().toString("yyyy-MM-dd"), changeEvent));
        return changeValues;
    }

    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinTable(name = "ClassYear_Learner", joinColumns = @JoinColumn(name = "LearnerId"),
            inverseJoinColumns = @JoinColumn(name = "ClassYearId"))
    public List<ClassYear> getClassYears() {
        return this.classYears;
    }

    public void setClassYears(List<ClassYear> classYears) {
        this.classYears = classYears;
    }

    @OneToMany(mappedBy = "learner")
    @Cascade({MERGE, PERSIST, SAVE_UPDATE, DETACH, DELETE})
    public List<SubjectEvaluation> getSubjectEvaluations() {
        return this.subjectEvaluations;
    }

    public void setSubjectEvaluations(List<SubjectEvaluation> subjectEvaluations) {
        this.subjectEvaluations = subjectEvaluations;
    }

    @OneToMany(mappedBy = "learner")
    @Cascade({MERGE, PERSIST, SAVE_UPDATE, DETACH, DELETE})
    public List<TopicEvaluation> getTopicEvaluations() {
        return this.topicEvaluations;
    }

    public void setTopicEvaluations(List<TopicEvaluation> topicEvaluations) {
        this.topicEvaluations = topicEvaluations;
    }

}
